/**
 *  mem.h - Memory management.
 *
 *  Copyright (C) 2008-2010 ZhangHu
 *  All rights reserved.
 *  E-MAIL: anmnmnly@gmail.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MM_H__
#define __MM_H__


#include "include/types.h"

#ifndef UNIT_DEBUG
#include "include/list.h"
#include "include/irq.h"
#include "hw_mem.h"
#endif


#define MEM_FREE 0x0     // Block is free.
#define MEM_ALLOC 0x1     // Block is allocated.

typedef struct page_struct
{
    uint32 size;                // Block size.
    uint32 status;              // Status that is frre or allocate.
    list_t free_link;            // Link to the next free block.
    struct page_struct *mem_up;  // Link to the upper block.
    struct page_struct *mem_down;// Link to the lower block.
} page_t;

// some blocks that linked by this struct, in which
// all size is in a certain range.
struct free_struct {
    list_t free_link;   // pointer to the first block
    uint32 size;       // the maxium size in this group block
};

// Initialize memory
extern void initmem(void);

// get start address of memory
extern int32 get_start_address(void);


// allocate - Assign a size of 'Size' space for application.
// This function is the main routine for assignment memory.
// However, applications do not called it directly. It can use to
// driver or some parts of kernel.
extern void *allocate(int32 Size);

// kmalloc - Assign a size of 'Size' space for application.
// It calls 'allocate()' directly after turn off interruption.
// Applictions should use it for assignment memory.
extern void *kmalloc(int32 Size);

// reclaim - Reclaiming a block space.
// This function is the main routine for Reclaiming memory.
// However, applications do not called it directly. It can use to
// driver or some parts of kernel.
extern void reclaim(void *pfree);

// kfree - Reclaiming a block space.
// It calls 'free()' directly after turn off interruption.
// Applictions should use it for Reclaiming memory.
extern void kfree(void *pfree);

// kfree - Set all member of a buffer to 'ch'
extern void kmemset(void *buffer, char_t ch, uint32 len);

// Get the start address of memory
extern page_t *kgetmemlist(void);


#endif

